#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<pthread.h>
#include<unistd.h>

/*
	如果不加锁，则在消费者先执行的情况下head为空，则出现段错误
*/


//创建线程锁
pthread_mutex_t mutex;

//创建链表结构体
typedef struct node
{
	int date;
	struct node * pnext;

}NODE;

//创建共享数据
NODE *head = NULL;

//定义条件变量
pthread_cond_t cond;

//生产者----->在链表中加入数据　　头插
void *producer(void *arg)
{
	NODE *pNode = NULL;
	while(1)
	{
		//生产一个节点
		pNode = (NODE *)malloc(sizeof(NODE));
		if(pNode == NULL)
		{
			perror("malloc error");
			exit(-1); //进程退出
		}
		//加锁
		pthread_mutex_lock(&mutex);

		pNode->pnext = head;
		pNode->date = rand()%100+1;
		printf("p:[%d]\n",pNode->date);
		head = pNode;

		//解锁
		pthread_mutex_unlock(&mutex);

		//唤醒阻塞的线程
		pthread_cond_signal(&cond);
		
		sleep(rand()%3);
	}

	return 0;
}

//消费者
void *consumer(void *arg)
{	
	NODE *pNode = NULL;
	while(1)
	{
		//加锁
		pthread_mutex_lock(&mutex);

		if(head == NULL)
		{
			//如果条件不满足，阻塞等待
			pthread_cond_wait(&cond,&mutex);
		}

		printf("c:[%d]\n",head->date);
		pNode = head;
		head = head->pnext;

		//解锁
		pthread_mutex_unlock(&mutex);
		
		free(pNode);
		pNode = NULL;
		sleep(rand()%3);
	}
	return 0;
}


int main()
{
	//初始化锁
	 pthread_mutex_init(&mutex,NULL);
	
	//初始化条件变量
	pthread_cond_init(&cond,NULL);
	
	//创建生产者线程
	pthread_t thread1;
	int res = pthread_create(&thread1,NULL,producer,NULL);
	if(res!=0)
	{
		printf("pthread_create error,[%s]\n",strerror(res));
		return -1;
	}

	//创建消费者线程
	pthread_t thread2;
	res = pthread_create(&thread2,NULL,consumer,NULL);
	if(res!=0)
	{
		printf("pthread_create error,[%s]\n",strerror(res));
		return -1;
	}

	//线程回收
	pthread_join(thread1,NULL);
	pthread_join(thread2,NULL);

	//销毁锁
	pthread_mutex_destroy(&mutex);

	//销毁条件变量
	pthread_cond_destroy(&cond);
	return 0;
}
